﻿using Service.ZSJL.Com.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace Service.ZSJL.Com.Net
{
    public class HttpRequestUtils
    {
        private HttpRequestConfig _cfg;




        /// <summary>
        /// HTTP请求工具类，参数；
        /// </summary>
        /// <param name="cfg"></param>
        public HttpRequestUtils(HttpRequestConfig cfg)
        {
            this._cfg = cfg;

        }

        /// <summary>
        /// GET 访问数据，url传参数
        /// </summary>
        /// <returns></returns>
        public string HttpGet()
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_cfg.url);
            req.Method = MethodType.Get.ToString();
            req.ContentType = _cfg.MimeType == "" ? MimeType.GetMimeType(".html") : _cfg.MimeType;
            string reurl = "";
            if (_cfg.Encoding == null)
                _cfg.Encoding = Encoding.UTF8;
            WebResponse wr = req.GetResponse();
            using (var streamReader = new StreamReader(wr.GetResponseStream(), _cfg.Encoding))
            {
                reurl = streamReader.ReadToEnd();
            }
            return reurl;
        }


        /// <summary>
        /// GET 访问数据，url传参数
        /// </summary>
        /// <returns></returns>
        public string HttpGet(HttpRequestConfig cfg)
        {
            this._cfg = cfg;
            return HttpGet();
        }


        /// <summary>
        /// GET 访问数据，url传参数
        /// </summary>
        /// <returns></returns>
        public string HttpGet(string url)
        {
            this._cfg = new HttpRequestConfig();
            this._cfg.url = url;
            return HttpGet();
        }
        private FileStream GetFileStream(string fileName)
        {
            FileStream fileStream = null;
            if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
            {
                fileStream = new FileStream(fileName, FileMode.Open);
            }
            return fileStream;
        }

        /// <summary>
        /// 发送消息 Post
        /// </summary>
        /// <param name="JSONData"></param>
        /// <param name="Url"></param>
        /// <returns></returns>
        public string GetResponseData(string JSONData, string Url)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(JSONData);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = "POST";
            request.ContentLength = bytes.Length;
            request.ContentType = "text/xml";
            Stream reqstream = request.GetRequestStream();
            reqstream.Write(bytes, 0, bytes.Length);

            //声明一个HttpWebRequest请求  
            request.Timeout = 90000;
            //设置连接超时时间  
            request.Headers.Set("Pragma", "no-cache");
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream streamReceive = response.GetResponseStream();
            Encoding encoding = Encoding.UTF8;

            StreamReader streamReader = new StreamReader(streamReceive, encoding);
            string strResult = streamReader.ReadToEnd();
            streamReceive.Dispose();
            streamReader.Dispose();

            return strResult;
        }

        /// <summary>
        /// 使用Post方法获取字符串结果
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cookieContainer"></param>
        /// <param name="postStream"></param>
        /// <param name="fileDictionary">需要上传的文件，Key：对应要上传的Name，Value：本地文件名</param>
        /// <returns></returns>
        public string HttpPost(string url, CookieContainer cookieContainer, Stream postStream, Dictionary<string, string> fileDictionary, string refererUrl, Encoding encoding)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";

            #region 处理Form表单文件上传
            var formUploadFile = fileDictionary != null && fileDictionary.Count > 0;//是否用Form上传文件
            if (formUploadFile)
            {
                //通过表单上传文件
                postStream = new MemoryStream();

                string boundary = "----" + DateTime.Now.Ticks.ToString("x");
                //byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
                string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";

                foreach (var file in fileDictionary)
                {
                    try
                    {
                        var fileName = file.Value;
                        //准备文件流
                        using (var fileStream = GetFileStream(fileName))
                        {
                            var formdata = string.Format(formdataTemplate, file.Key, fileName /*Path.GetFileName(fileName)*/);
                            var formdataBytes = Encoding.ASCII.GetBytes(postStream.Length == 0 ? formdata.Substring(2, formdata.Length - 2) : formdata);//第一行不需要换行
                            postStream.Write(formdataBytes, 0, formdataBytes.Length);

                            //写入文件
                            byte[] buffer = new byte[1024];
                            int bytesRead = 0;
                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                postStream.Write(buffer, 0, bytesRead);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                //结尾
                var footer = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                postStream.Write(footer, 0, footer.Length);

                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            }
            else
            {
                request.ContentType = "application/x-www-form-urlencoded";
            }
            #endregion

            request.ContentLength = postStream != null ? postStream.Length : 0;
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            request.KeepAlive = true;

            if (!string.IsNullOrEmpty(refererUrl))
            {
                request.Referer = refererUrl;
            }
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";

            if (cookieContainer != null)
            {
                request.CookieContainer = cookieContainer;
            }

            #region 输入二进制流
            if (postStream != null)
            {
                postStream.Position = 0;

                //直接写入流
                Stream requestStream = request.GetRequestStream();

                byte[] buffer = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    requestStream.Write(buffer, 0, bytesRead);
                }

                postStream.Close();//关闭文件访问
            }
            #endregion

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (cookieContainer != null)
            {
                response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
            }

            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(responseStream, encoding ?? Encoding.GetEncoding("utf-8")))
                {
                    string retString = myStreamReader.ReadToEnd();
                    return retString;
                }
            }
        }

        /// <summary>
        /// post 访问数据，有数据内容
        /// </summary>
        /// <returns></returns>
        public string HttpPost()
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(_cfg.url);
            httpWebRequest.Method = MethodType.Post.ToString();
            httpWebRequest.ContentType = _cfg.MimeType;
            string result = "";
            if (_cfg.Encoding == null)
                _cfg.Encoding = Encoding.UTF8;


            httpWebRequest.Timeout = 90000;
            //设置连接超时时间  
            httpWebRequest.Headers.Set("Pragma", "no-cache");

            if (!string.IsNullOrEmpty(_cfg.DataContent))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(_cfg.DataContent);
                httpWebRequest.ContentLength = bytes.Length;


                using (var streamWriter = httpWebRequest.GetRequestStream())
                {
                    if (!string.IsNullOrEmpty(_cfg.DataContent))
                    {
                        streamWriter.Write(bytes, 0, bytes.Length);
                    }
                    streamWriter.Flush();
                    streamWriter.Close();

                    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream(), _cfg.Encoding))
                    {
                        result = streamReader.ReadToEnd();
                    }
                }
            }
            else
            {

                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(_cfg.DataContent);
                    streamWriter.Flush();
                    streamWriter.Close();
                    if (_cfg.Encoding == null)
                        _cfg.Encoding = Encoding.UTF8;
                    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream(), _cfg.Encoding))
                    {
                        result = streamReader.ReadToEnd();
                    }
                }
            }
            return result;
        }
    }




    /// <summary>
    /// /
    /// </summary>
    public class HttpRequestConfig
    {

        public string url { get; set; }
        public string encodeType { get; set; }
        public string MimeType { get; set; }
        public string DataContent { get; set; }
        public MethodType Method { get; set; }
        public Encoding Encoding { get; set; }

    }

    public enum MethodType
    {
        Get,
        Post
    }
}
